home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr05
/
xnot12a.zip
/
MOUSE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-20
|
12KB
|
508 lines
#include "jam.h"
#ifdef WINDOWED /* whole file */
/*
* Mouse support routines. Some code taken from original Amigamouse
* code in Mg2a and enhanced/modified almost beyond recognition. This
* code supports
*
* set mark
* set dot
* select region and copy/kill it
* resize window(s)
* scroll window(s)
*
* via string commands stuffed into the input stream from the
* window level code. It ain't pretty, but it gets the job done.
*
*/
#include "def.h"
#include "stdio.h"
#include "keyname.h"
#include "macro.h"
#include "kbd.h"
/* string-to-verb matching for mousecmd subcommands
*/
#define LEFTDOWN 0
#define RIGHTDOWN 1
#define LEFTUP 2
#define MOVE 3
#define DBLCLICK 4
#define LEFTDOWNSHIFT 5
#define M_ABORT 6
#define M_TIMER 7
static BOOL rn_(setmousepos,(int row, int col, BOOL left));
static void rn_(movedot,(int row, int col));
static int rn_(subcommand,(char *s));
static int downrow = -1, downcol = -1; /* initial down during move.. */
static int oldrow = -1, oldcol = -1; /* last mouse click */
static int newrow, newcol; /* next mouse click */
static BOOL inmodeline = FALSE;
static BOOL bottommodeline = FALSE;
static BOOL mouseDown = FALSE;
static BOOL mouseMoving = FALSE;
static EWINDOW *touchedWp;
static BOOL mshift = FALSE;
static BOOL didsetmark = FALSE;
static EWINDOW *mwp, *mwp1; /* window(s) mouse is in */
static int mdoto, mdoto1, mcol1; /* line offset of mouse */
static LINE *mdotp, *mdotp1; /* the real line the mouse is on */
static char *cancel = "Cancelled!";
static char *diffw = "Different window.";
static char *shiftm = "Shift key will reverse scroll direction.";
static char *movecopy = "Mark set; move cursor (dot) to define region to %s.";
static char *mv = "move";
static char *cp = "copy";
/* relative-command - return if last click was in modeline
*/
BOOL minmodeline()
{
return (inmodeline);
}
/*
* Utility routine to move dot to where the user clicked.
* Optional 'move' flag to make move permanent vs just
* locating new dot.
*/
int dottomouse(inrow, incol, move)
int inrow;
int incol;
BOOL move;
{
register EWINDOW *wp;
register int dot;
register int col;
register int c, nlines;
inmodeline = FALSE; /* always reset */
bottommodeline = FALSE;
newrow = inrow;
newcol = incol;
if (macrodef)
{
ewprintf(notinmacro);
return (FALSE);
}
/* Find out which window was clicked in
*/
for (wp = wheadp; wp != NULL; wp = wp->w_wndp)
if (newrow == (wp->w_toprow + wp->w_ntrows))
{
touchedWp = wp;
inmodeline = TRUE;
if (!wp->w_wndp) /* no next window? */
bottommodeline = TRUE;
}
else if ((newrow >= wp->w_toprow) &&
(newrow <= (wp->w_toprow + wp->w_ntrows)))
break;
/* Impossible?
*/
if (wp == NULL)
return (ABORT);
else /* Compute the new location; optionally move there */
{
EWINDOW *savewp = curwp;
BUFFER *savebp = curbp;
LINE *savedotp = curwp->w_dotp;
int savedoto = curwp->w_doto;
/* Move to selected window, move dot to top left
* then advance as possible to mouse point.
*/
curwp = wp;
curbp = wp->w_bufp;
curwp->w_dotp = wp->w_linep;
curwp->w_doto = 0;
/* Go forward the correct # of lines
*/
nlines = newrow - curwp->w_toprow;
for (; nlines > 0; nlines--)
{
/* Wrap around? Don't insert blank lines in file
*/
if (lforw(curwp->w_dotp) == curbp->b_linep)
break;
forwline(FFRAND, 1);
}
/* Go forward the correct # of characters
* need to count them out because of tabs
*/
col = dot = 0;
while ((col < newcol) && (dot < llength(curwp->w_dotp)))
{
c = lgetc(curwp->w_dotp, dot++);
if (c == CCHR('I'))
col |= TABROUND;
else if (ISCTRL(c) != FALSE)
++col;
++col;
}
if (col > newcol)
dot--; /* back up to tab/ctrl char */
forwchar(FFRAND, dot);
/* not supposed to move? reset but remember where it
* would have been
*/
mwp = curwp;
mdoto = curwp->w_doto;
mdotp = curwp->w_dotp;
if (!move)
{
curwp = savewp;
curbp = savebp;
curwp->w_dotp = savedotp;
curwp->w_doto = savedoto;
}
}
return (TRUE);
}
/* Handle mouse generated things
*/
int mousecmd(f, n)
int f, n;
{
char buf[256];
int subcmd;
static int row, col;
BOOL killit = FALSE;
static BOOL drawn = FALSE;
#define IsAbort ((subcmd == M_ABORT) || killit)
#define SetAbort() killit = TRUE
/* Read the subcommand which is waiting in input stream.
*/
getcmdinput(buf);
if (buf[0])
{
subcmd = subcommand(buf); /* Convert subcommand to verb */
switch(subcmd)
{
case M_ABORT:
ewprintf(cancel);
ttbeep();
/* FALLTHRU */
case LEFTUP:
{
BOOL copy = FALSE;
BOOL kill = FALSE;
EWINDOW *savewp = curwp;
BUFFER *savebp = curbp;
LINE *savedotp = curwp->w_dotp;
int savedoto = curwp->w_doto;
/* make window cursor normal, then find
* position UP occurred
*/
WindowNormalCursor();
if (drawn) /* erase old */
{
movedot(row, col);
drawn = FALSE;
}
if (!IsAbort) /* abort has no params */
{
getcmdinput(buf);
sscanf(buf, posFormat, &row, &col);
}
if (!mouseDown) /* up after abort? */
return (TRUE); /* no other bell */
if (inmacro)
{
ewprintf(notinmacro);
return FALSE; /* can't record mouse actions */
}
if (didsetmark) /* didn't do this for modeline move */
{
if (IsCaretCreated())
SetCaretVis(FALSE); /* make sure no display weirdness */
if (mwp1 != mwp)
{
ewprintf(diffw); /* operation can't span windows */
SetAbort();
}
curwp = savewp;
curbp = savebp;
curwp->w_dotp = savedotp;
curwp->w_doto = savedoto;
/* Set dot at up point. If real motion occurred,
* set appropriate verb (copy/kill).
*/
if (!IsAbort)
{
dottomouse(row, col, TRUE);
if ((mwp1 == mwp) && (mdotp != mdotp1) ||
(mdoto != mdoto1))
{
if (mshift)
kill = TRUE;
else
copy = TRUE;
}
} /* end !IsAbort */
} /* end didsetmark */
/* if an action triggered, do it now
*/
if (copy)
{
kdelete();
copyregion(0, 1);
}
else if (kill)
killregion(0, 1);
/* verboseness... remind that something can be pasted
*/
if (copy || kill)
ewprintf(pastemsg);
mshift = FALSE;
mouseMoving = mouseDown = FALSE;
didsetmark = FALSE;
}
break;
case LEFTDOWN:
case LEFTDOWNSHIFT:
mshift = (subcmd == LEFTDOWNSHIFT? TRUE: FALSE);
getcmdinput(buf);
if (inmacro)
{
ewprintf(notinmacro);
return FALSE; /* can't record mouse actions */
}
sscanf(buf, posFormat, &row, &col);
return(setmousepos(row, col, TRUE));
case DBLCLICK:
if (inmacro)
{
ewprintf(notinmacro);
return FALSE; /* can't record mouse actions */
}
/* mouse-dblclick really should be the end result of
* of clicking the mouse, then users could map that action
* just like any keyboard key. But I don't feel like doing
* that, and in reality NO ui should directly do anything but
* insert pseudo keystrokes for mapping... in a perfect world.
*/
if (!inmodeline && (curbp->b_modes[0] == name_mode(DiredStr)))
return(d_findfile(0, 1));
else if (!inmodeline && (curbp->b_modes[0] == name_mode(BlistStr)))
return(seebuffer(0, 1));
else
{
ewprintf("Mouse setting mark...");
return(setmark(0, 1));
}
case RIGHTDOWN:
{
int s;
getcmdinput(buf);
if (inmacro)
{
ewprintf(notinmacro);
return FALSE; /* can't record mouse actions */
}
sscanf(buf, posFormat, &row, &col);
s = setmousepos(row, col, FALSE);
if (s)
yank(0, 1);
return (s);
}
case M_TIMER:
{
int shifted;
if (drawn)
{
movedot(row, col); /* erase old */
drawn = FALSE;
}
ewprintf(shiftm);
getcmdinput(buf);
sscanf(buf, "%d", &shifted);
if (shifted)
ExtendedFunction(function_name(back1page));
else
ExtendedFunction(function_name(forw1page));
break;
}
case MOVE:
{
EWINDOW *save;
int delta;
int row_ = row; /* last move row, col */
int col_ = col;
getcmdinput(buf);
if (!mouseDown) /* abort occurred? */
return (TRUE); /* leave quietly */
if (inmacro)
{
ewprintf(notinmacro);
return FALSE; /* can't record mouse actions */
}
sscanf(buf, posFormat, &row, &col);
/* button down hit mode line?
*/
if (inmodeline && !mouseMoving) /* moving for selection? */
{
if (bottommodeline)
ewprintf(Impossible);
else
{
WindowSizeCursor();
save = curwp;
curwp = touchedWp;
oldrow = touchedWp->w_toprow + touchedWp->w_ntrows - 1;
delta = abs(row - oldrow);
if (row < oldrow)
shrinkwind(0, delta);
else
enlargewind(0, delta);
curwp = save;
oldrow = row;
}
}
/* button down hit source window?
*/
else
{
if (!mouseMoving)
{
setmark(0, 1);
movedot(row, col);
}
else if ((row_ != row) || (col_ != col))
{
if (drawn)
movedot(row_, col_); /* erase old */
movedot(row, col); /* draw new */
}
if (!drawn)
ewprintf(movecopy, mshift ? mv : cp);
drawn = TRUE;
WindowDragCursor();
mouseMoving = TRUE;
}
}
default:
break; /* nothing of interest */
}
}
/* gobbledy-goop
*/
return TRUE;
}
/* set dot to row/col, conditionally sets static state
* variables concerning down position
*/
static BOOL setmousepos(row, col, left)
int row;
int col;
BOOL left;
{
if (!dottomouse(row, col, TRUE)) /* sets newrow, newcol */
return (FALSE);
if (!left)
return (TRUE);
downrow = oldrow = newrow; /* save state */
downcol = oldcol = newcol;
mouseDown = TRUE;
mouseMoving = FALSE;
mwp1 = mwp; /* save across move */
mdotp1 = mdotp;
mdoto1 = mdoto;
mcol1 = getcolpos() - 1; /* evaluated location */
/* get globals to the right place...draw a marker
*/
WindowArrowCursor(); /* kinda limbo cursor.. */
ewprintf("Cntrl-left is scroll; drag for region select.");
if (!inmodeline)
if (g_hasFocus)
{
update();
didsetmark = TRUE;
}
return (TRUE);
}
/* visible region-selection drawing...
*/
static void movedot(row, col)
int row, col;
{
dottomouse(row, col, TRUE);
update();
DrawMarker();
ttflush(FALSE);
}
/* parse a subcommand string to a integer verb
*/
static int subcommand(s)
char *s;
{
/* this just moves the strcmp's out of direct sight!
*/
if (strcmp(s, LeftUp) == 0)
return(LEFTUP);
else if (strcmp(s, RightDwn) == 0)
return(RIGHTDOWN);
else if (strcmp(s, LeftDwn) == 0)
return(LEFTDOWN);
else if (strcmp(s, LeftDwnShift) == 0)
return(LEFTDOWNSHIFT);
else if (strcmp(s, DoubleClick) == 0)
return(DBLCLICK);
else if (strcmp(s, MoveStr) == 0)
return(MOVE);
else if (strcmp(s, MouseAbort) == 0)
return(M_ABORT);
else if (strcmp(s, MouseTimer) == 0)
return(M_TIMER);
/* unknown */
else
return (-1);
}
#endif /* WHOLE FILE */